package com.mazj.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mazj.beans.Car;
import com.mazj.beans.Person;
import com.mazj.exception.LackParamException;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Controller
public class IndexController {

    /**
     * springMvc 使用servlet对象，直接在参数中定义需要的Servlet对象即可
     *
     * 示例中使用session
     *
     * 什么是cookie(甜饼)?
     * HTTP协议是无状态的协议。一旦数据交换完毕，客户端与服务器端的连接就会关闭，再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。
     *
     * cookie数据存放在客户的浏览器上，session数据放在服务器上.
     * cookie不是很安全，别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session
     * 设置cookie时间可以使cookie过期。但是使用session-destory（），我们将会销毁会话
     * session会在一定时间内保存在服务器上。当访问增多，会比较占用你服务器的性能考虑到减轻服务器性能方面，应当使用cookie
     * 单个cookie保存的数据不能超过4K，很多浏览器都限制一个站点最多保存20个cookie。(Session对象没有对存储的数据量的限制，其中可以保存更为复杂的数据类型)
     * 两者最大的区别在于生存周期，一个是IE启动到IE关闭.(浏览器页面一关 ,session就消失了)，一个是预先设置的生存周期，或永久的保存于本地的文件。(cookie)
     *
     * @param session
     * @return
     */
    @RequestMapping("/index")
    public String home(HttpSession session){
        System.out.println("sessionId:" + session.getId());
        return "index";
    }


    @RequestMapping(value = "/list",method = RequestMethod.GET)
    public String list(){
        return "user/list";
    }

    @RequestMapping(value = "/delete/{id}",method = RequestMethod.DELETE)
    public String delete(HttpServletRequest request,@PathVariable("id") Integer id){
        System.out.println("进入delete");
        System.out.println("request.getContextPath():" + request.getContextPath());
        System.out.println("request.getServletPath():" + request.getServletPath());
        System.out.println("request.getRequestURL():" + request.getRequestURL());
        System.out.println("id:" + id);
        return "redirect:/list";
    }


    // 可以使用@ExceptionHandler处理特定Controller的特定异常
    @ExceptionHandler(NumberFormatException.class)
    public ModelAndView handException(Exception ex){
        System.out.println("出现异常:" + ex);
        ModelAndView mv = new ModelAndView();
        mv.setViewName("error");
        mv.addObject("exception", ex);
        return mv;
    }


    @ExceptionHandler(LackParamException.class)
    public ModelAndView handLackParamException(Exception ex){
        System.out.println("出现异常:" + ex);
        ModelAndView mv = new ModelAndView();
        mv.setViewName("error");
        mv.addObject("exception", ex);
        return mv;
    }
    // 自定义异常LackParamException，先创建异常类继承ServletException，之后在异常地方直接抛出即可
    @RequestMapping(value = "/test_exception",method = RequestMethod.GET)
    public String test_exception(String str) throws LackParamException {
        System.out.println("test_exception");
        if(StringUtils.isEmpty(str)){
            throw new LackParamException("缺少参数");
        }
        return "redirect:/list";
    }

    @RequestMapping(value = "/update/{id}",method = RequestMethod.PUT)
    public String update(@PathVariable("id") Integer id) throws LackParamException {
        System.out.println("进入update");
        System.out.println("id:" + id);
        return "redirect:/list";
    }

    /**
     * 返回json
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/person-json",method = RequestMethod.GET)
    public Person testPersonJson(){
        // 制造异常测试全局异常ExceptionHandler
//        int a = 9/0;
        Person person = new Person(
                "xiaoming",22,new Car("coco",400000,200)
        );
        return person;
    }

    @ResponseBody
    @RequestMapping(value = "/list-json",method = RequestMethod.GET)
    public List<Person> testPersonsJson(){
        List<Person> list = new ArrayList<Person>();
        Person person = new Person(
                "xiaoming",22,new Car("baoma",400000,200)
        );
        list.add(person);
        person = new Person(
                "xiaohong",20,new Car("coco",100000,100)
        );
        list.add(person);
        return list;
    }


    @RequestMapping(value = "/form2",method = RequestMethod.GET)
    public String form2(){
        return "user/form2";
    }


    /**
     * jsonp的使用，可用来解决跨域问题
     * @param callback
     * @param response
     * @throws JsonProcessingException
     */
    @RequestMapping(value = "/jsonp",method = RequestMethod.GET)
    public void jsonp(String callback, HttpServletResponse response) throws IOException {
        System.out.println("进入jsonp");
        Person person = new Person(
                "xiaoming",22,new Car("baoma",400000,200)
        );
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(person);
        response.getWriter().println(callback + "(" + json + ")");
    }

    @RequestMapping(value = "/save-json",method = RequestMethod.POST)
    public @ResponseBody Person saveJson(@RequestBody Person person) throws IOException {
        System.out.println("进入save-json");
        System.out.println("传入的person=>" + person);
        // 测试懒得多写,直接将person作为json返回进行
        return person;
    }

    @RequestMapping("fileupload")
    public String fileUpload(String desc, MultipartFile file, Model model) throws IOException {
        System.out.println("进入文件上传,desc:" + desc + ",file:" + file);
        String filePath = "D:\\upload\\";
        // 前台传过来的文件名
        String origName = file.getOriginalFilename();
        // 扩展名
        String extendsName = null;
        if(file != null && origName != null && origName.length()>0){
            System.out.println("origName:" + origName);
            extendsName = origName.substring(origName.lastIndexOf("."));
            File dir = new File(filePath);
            if(!dir.exists()){
                dir.mkdir();
            }
            File uploadFile = new File(filePath + UUID.randomUUID().toString() + extendsName);
            file.transferTo(uploadFile);
            model.addAttribute("filepath", "/file/" + UUID.randomUUID().toString() + extendsName);
        }
        return "success";
    }
}
